package com.autonavi.yunda.yunji.core.engine.context;

import com.autonavi.yunda.yunji.core.enums.NodeType;
import com.autonavi.yunda.yunji.core.vo.node.BaseNode;
import com.autonavi.yunda.yunji.core.vo.param.NodeParam;
import com.autonavi.yunda.yunji.core.vo.param.ParamValidator;
import lombok.Getter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 树结构的节点
 * @author cizhong.wcs
 * @date 2023/8/23 13:59
 */
@Getter
public class Node {
    /**
     * 节点名称
     */
    private final String name;
    /**
     * 节点类型
     */
    private final NodeType nodeType;
    /**
     * 节点别名
     */
    private final String var;
    /**
     * 参数名-参数类型 map
     */
    private final Map<String, String> paramNameTypeMap;
    /**
     * 结果校验集合
     */
    private final List<ParamValidator> resultValidators;
    private long nodeTimeoutMillis = 60000;
    /**
     * 下级节点集合
     */
    private final List<String> nextNodes = new ArrayList<>();
    /**
     * 上级节点集合
     */
    private final List<String> previousNodes = new ArrayList<>();
    /**
     * 下级节点名称-分支条件函数名称（switcher_本节点名称_下级节点名称） map
     */
    private final Map<String, String> nodeSwitcherFunctionMap = new HashMap<>();
    /**
     * 分支条件函数名称-参数映射 map
     */
    private final Map<String, Map<String, String>> nodeSwitcherParamNameTypeMap = new HashMap<>();
    private final List<String> defaultNextNodes = new ArrayList<>();

    public Node(BaseNode node) {
        this.name = node.name;
        this.var = node.var;
        this.nodeType = node.nodeType;
        this.resultValidators = node.resultValidators;
        this.paramNameTypeMap = node.params.stream().collect(Collectors.toMap(NodeParam::getParamNameInScript, NodeParam::getType));
        if (node.nodeTimeoutMillis != null) {
            this.nodeTimeoutMillis = node.nodeTimeoutMillis;
        }
    }

    public void addNext(String name) {
        nextNodes.add(name);
    }

    public void addPrevious(String name) {
        previousNodes.add(name);
    }

    public void addDefaultNextNodes(String name) {
        defaultNextNodes.add(name);
    }

    public void addSwitcher(String name, String functionName, List<NodeParam> params) {
        nodeSwitcherFunctionMap.put(name, functionName);
        nodeSwitcherParamNameTypeMap.put(functionName, params.stream().collect(Collectors.toMap(NodeParam::getParamNameInScript, NodeParam::getType)));
    }
}
